package com.shine.commonlibrary.utils.base;


import android.Manifest;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;

import com.shine.commonlibrary.BuildConfig;
import com.shine.commonlibrary.R;
import com.shine.commonlibrary.utils.basemvp.BaseModel;
import com.shine.commonlibrary.utils.basemvp.BasePresenter;
import com.shine.commonlibrary.utils.baserx.RxManager;
import com.shine.commonlibrary.utils.commonwidget.LoadingDialog;
import com.shine.commonlibrary.utils.commonwidget.StatusBarCompat;
import com.shine.commonlibrary.utils.daynightmode.ChangeModeController;
import com.shine.commonlibrary.utils.manager.ActivityManager;
import com.shine.commonlibrary.utils.updateapp.ConfirmDialog;
import com.shine.commonlibrary.utils.updateapp.UpdateAppCallback;
import com.shine.commonlibrary.utils.utils.LogUtils;
import com.shine.commonlibrary.utils.utils.ToastUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import kr.co.namee.permissiongen.PermissionFail;
import kr.co.namee.permissiongen.PermissionGen;
import kr.co.namee.permissiongen.PermissionSuccess;

/**
 * Created by M_genius on 2017/9/6 14:17.
 * 描述：基类Activity
 * 以 MVP 模式进行封装
 */
public abstract class BaseActivity<P extends BasePresenter, M extends BaseModel> extends AppCompatActivity {

    public P mPresenter;
    public M mModel;
    public BaseActivity mContext;
    public RxManager mRxManager;
    private static String ACTIVITY_TAG = "BaseActivity";

    private Dialog mDialog;
    private HashMap<String, Fragment> fragmentCache;

    //请求SDCard权限的常量
    private static final int REQUEST_CODE_SDCARD = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ACTIVITY_TAG = getClass().getSimpleName();
        LogUtils.d(ACTIVITY_TAG + ":onCreate~~~");
        super.onCreate(savedInstanceState);

        //初始化RxBus、RxJava管理器
        mRxManager = new RxManager();

        //用于缓存页面中的Fragment
        fragmentCache = new HashMap<>();

        //设置状态栏
        doBeforeSetContentView();
        setContentView(getLayoutId());

        mContext = this;

        this.initPresenter();
        if (mPresenter != null) {
            mPresenter.mContext = this;
        }
        init();

        checkAppUpdate();
    }

    /**
     * 检测App是否更新，进行了权限验证
     */
    private void checkAppUpdate() {

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            update();
        } else {
            if (ContextCompat.checkSelfPermission(BaseActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                update();
            } else {
                //申请权限
                PermissionGen.with(BaseActivity.this)
                        .addRequestCode(REQUEST_CODE_SDCARD)
                        .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        .request();
            }
        }
    }

    /**
     *
     *  1、重写update方法，请求服务器的versionCode、versionName
     *  2、请求成功，调用一下代码，更新App
     *
     *  UpdateAppUtils.from(LoginActivity.this)
            .serverVersionCode(Integer.parseInt(updateAppEntity.getObj().getVersionNum()))
            .serverVersionName(updateAppEntity.getObj().getVersionName())
            .apkPath(updateAppEntity.getObj().getLink())
            .updateInfo("")
          //.showNotification(false)
            .update();
     */
    protected void update(){}

    /**
     * 权限申请成功
     */
    @PermissionSuccess(requestCode = REQUEST_CODE_SDCARD)
    public void doSomething() {
        Toast.makeText(this, "权限申请成功", Toast.LENGTH_SHORT).show();
        update();
    }

    /**
     * 权限申请失败
     */
    @PermissionFail(requestCode = REQUEST_CODE_SDCARD)
    public void doFailSomething() {
        Toast.makeText(this, "权限申请失败", Toast.LENGTH_SHORT).show();
        new ConfirmDialog(this, new UpdateAppCallback() {
            @Override
            public void callback(int position) {
                if (position == 1) {
                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    intent.setData(Uri.parse("package:" + getPackageName())); // 根据包名打开对应的设置界面
                    startActivity(intent);
                }
            }
        }).setContent("暂无读写SD卡权限\n是否前往设置？").show();
    }



    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        LogUtils.d(ACTIVITY_TAG + ":onRestoreInstanceState~~~");
    }


    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        LogUtils.d(ACTIVITY_TAG + ":onConfigurationChanged~~~");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        LogUtils.d(ACTIVITY_TAG + ":onRestart~~~");
    }

    @Override
    protected void onStart() {
        super.onStart();
        LogUtils.d(ACTIVITY_TAG + ":onStart~~~");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        LogUtils.d(ACTIVITY_TAG + ":onSaveInstanceState~~~");
    }

    /**
     * 设置layout前配置
     * 1、初始化主题
     * 2、Activity添加到Activity管理器
     * 3、设置状态栏的颜色，根据系统版本进行设置
     */
    private void doBeforeSetContentView() {
        //设置昼夜主题
        initTheme();
        // 把activity放到application栈中管理
        ActivityManager.getAppManager().addActivity(this);
        // 无标题
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 默认着色状态栏
        SetStatusBarColor();
    }

    /*********************
     * 子类实现
     *****************************/
    //获取布局文件
    public abstract int getLayoutId();

    /**
     * 简单页面无需mvp就不用管此方法即可,完美兼容各种实际场景的变通
     */

    protected void initPresenter() {

    }

    /**
     * 进行一些页面的初始化操作
     */
    protected void init() {
    }

    /**
     * 设置主题
     */
    private void initTheme() {
        ChangeModeController.setTheme(this, R.style.DayTheme, R.style.NightTheme);
    }

    /**
     * 着色状态栏（4.4以上系统有效）
     */
    protected void SetStatusBarColor() {
        StatusBarCompat.setStatusBarColor(this, ContextCompat.getColor(this, R.color.main_color));
    }

    /**
     * 着色状态栏（4.4以上系统有效）
     */
    protected void SetStatusBarColor(int color) {
        StatusBarCompat.setStatusBarColor(this, color);
    }

    /**
     * 沉浸状态栏（4.4以上系统有效），全屏模式
     */
    protected void SetTranslanteBar() {
        StatusBarCompat.translucentStatusBar(this);
    }

    /**
     * 设置页面全屏显示
     */
    protected void setFullScreenMode() {
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }


    @Override
    public void startActivity(Intent intent) {
        super.startActivity(intent);
    }

    /**
     * 通过Class跳转界面，不含参数
     **/
    public void startActivity(Class<?> cls) {
        startActivity(cls, null);

    }

    /**
     * 含有Bundle通过Class跳转界面
     **/
    public void startActivity(Class<?> cls, Bundle bundle) {
        Intent intent = new Intent();
        intent.setClass(this, cls);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
        overridePendingTransition(R.anim.activity_right_in, R.anim.activity_left_out);
    }

    /**
     * 通过Class跳转界面 不携带Bundle
     **/
    public void startActivityForResult(Class<?> cls, int requestCode) {
        startActivityForResult(cls, null, requestCode);
        overridePendingTransition(R.anim.activity_right_in, R.anim.activity_left_out);
    }

    /**
     * 通过Class跳转界面 携带Bundle
     **/
    public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
        Intent intent = new Intent();
        intent.setClass(this, cls);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivityForResult(intent, requestCode);
        overridePendingTransition(R.anim.activity_right_in, R.anim.activity_left_out);
    }

    @Override
    public void finish() {
        LogUtils.d(ACTIVITY_TAG + ":finish~~~");
        super.finish();
        overridePendingTransition(R.anim.activity_left_in, R.anim.activity_right_out);
    }

    /**
     * finish当前界面，是否启用动画
     *
     * @param closeAnim true：关闭时有动画，false：关闭是无动画
     */
    public void finish(boolean closeAnim) {
        super.finish();
        if (closeAnim) {
            overridePendingTransition(R.anim.activity_left_in, R.anim.activity_right_out);
        }
    }

    /**
     * 显示加载提示对话框，默认提示文字，加载中。。。
     */
    public void startProgressDialog() {
        mDialog = LoadingDialog.showDialogForLoading(this);
    }

    /**
     * 显示加载提示对话框，需要传入提示文字
     *
     * @param msg
     */
    public void startProgressDialog(String msg) {
        mDialog = LoadingDialog.showDialogForLoading(this, msg, true);
    }

    /**
     * 停止浮动加载进度条
     */
    public void stopProgressDialog() {
        if (mDialog != null) {
            mDialog.cancel();
        }
    }

    /**
     * 短暂显示Toast提示(来自String)
     **/
    public void showShortToast(String text) {
        ToastUtils.showShort(text);
    }

    /**
     * 短暂显示Toast提示(id)
     **/
    public void showShortToast(int resId) {
        ToastUtils.showShort(resId);
    }

    /**
     * 长时间显示Toast提示(来自res)
     **/
    public void showLongToast(int resId) {
        ToastUtils.showLong(resId);
    }

    /**
     * 长时间显示Toast提示(来自String)
     **/
    public void showLongToast(String text) {
        ToastUtils.showLong(text);
    }

    /**
     * 带图片的toast
     *
     * @param text
     * @param res
     */
    public void showToastWithImg(String text, int res) {
        ToastUtils.showToastWithImg(text, res);
    }

    /**
     * 网络访问错误提醒
     */
    public void showNetErrorTip() {
        ToastUtils.showToastWithImg(getText(R.string.net_error).toString(), R.drawable.icon_fail);
    }

    public void showNoNetTip() {
        ToastUtils.showToastWithImg(getText(R.string.no_net).toString(), R.drawable.icon_fail);
    }

    public void showNetErrorTip(String error) {
        ToastUtils.showToastWithImg(error, R.drawable.icon_fail);
    }

    /**
     *
     */
    @Override
    protected void onResume() {
        LogUtils.d(ACTIVITY_TAG + ":onResume~~~");
        super.onResume();
        //debug版本不统计crash
        if (!BuildConfig.LOG_DEBUG) {
            //友盟统计
        }
    }

    @Override
    protected void onPause() {
        LogUtils.d(ACTIVITY_TAG + ":onPause~~~");
        super.onPause();
        //debug版本不统计crash
        if (!BuildConfig.LOG_DEBUG) {
            //友盟统计
        }
    }


    @Override
    protected void onDestroy() {
        LogUtils.d(ACTIVITY_TAG + ":onDestroy~~~");
        ActivityManager.getAppManager().removeActivity(this);
        super.onDestroy();

        if (mPresenter != null) {
            mPresenter.onDestroy();
        }
        //Activity结束时，移除页面内所有的订阅关系
        mRxManager.clear();
    }

    protected void setFragment(@NonNull int containerViewId, BaseFragment fragment, String tag, boolean isUseAnim) {
        setFragment(containerViewId, fragment, null, tag, isUseAnim);
    }

    /**
     * 为Activity中的容器设置Fragment
     *
     * @param containerViewId 容器id
     * @param fragment
     * @param bundle          添加参数
     * @param tag
     * @param isUseAnim       fragment 切换是否有动画效果
     */
    protected void setFragment(@NonNull int containerViewId, BaseFragment fragment, Bundle bundle, String tag, boolean isUseAnim) {
        FragmentManager mFragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
//        是否加入回退栈
//        transaction.addToBackStack(null);
        if (isUseAnim) {
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        }
//        transaction.setCustomAnimations(R.animator.fragment_slide_right_enter, R.animator.fragment_slide_right_exit, R.animator.fragment_slide_right_enter, R.animator.fragment_slide_right_exit);
//        注意setCustomAnimations()方法必须在add、remove、replace调用之前被设置，否则不起作用。

        if (bundle != null) {
            fragment.setArguments(bundle);
        }
        transaction.add(containerViewId, fragment, tag);
        transaction.commit();
    }

    /**
     * 往同一容器中加入多个Fragment、hide，show的方式切换
     *
     * @param containerId
     * @param fragment
     * @param fragmentTag
     * @param isUseAnim
     */
    protected void showFragment(int containerId, Fragment fragment, String fragmentTag, boolean isUseAnim) {

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        if (isUseAnim) {
            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        }

        if (fragmentCache.get(fragmentTag) == null) {
            fragmentCache.put(fragmentTag, fragment);
            transaction.add(containerId, fragment, fragmentTag);
        }

        Iterator iterator = fragmentCache.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String key = (String) entry.getKey();
            if (key.equals(fragmentTag)) {
                transaction.show((Fragment) entry.getValue());
            } else {
                transaction.hide((Fragment) entry.getValue());
            }
        }

        transaction.commit();
    }

    /**
     * 跳转到系统的辅助功能页面
     */
    public void skipToSystemAssistActivity(){
        Intent intent =  new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        startActivity(intent);
    }

    /**
     * 跳转到网络设置界面
     */
    public void skipToNetworkSetActivity(){
        Intent intent =  new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS);
        startActivity(intent);
    }

}
